home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 001-025 / disk_009 / proff / pxxparse.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  10KB  |  508 lines

  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include "proff.h"
  4. #include "debug.h"
  5. #include "lextab.h"
  6.  
  7. #define RUNOFF    1         /* recognise RUNOFF commands */
  8.  
  9. char literal = NO;        /* literal flag             */
  10.  
  11. /*
  12.  * command - perform formatting command
  13.  *
  14.  */
  15. command(buf)
  16. char buf[];
  17. {
  18.     char token[MAXTOK], xtoken[MAXTOK], variable[MAXTOK], *defn;
  19.     char special[MAXTOK];
  20.     int argtyp, ct, at, spval, i, flags;
  21.     register int val, n, rest;
  22.     char onflag = FALSE; 
  23.     char offlag = FALSE;
  24.     struct lexlist *xp;
  25.  
  26.     dovar(tbuf1,buf);    /* use scratch buffer to expand variables */
  27.     strcpy(buf,tbuf1);
  28.  
  29.     i = 1;
  30.     n = getwrd(buf, &i, token);    /* get the command token */
  31.     rest = i;            /* remaining string */
  32.     ct = comtype(token, n, &defn, &flags);
  33.     if (ct == UNKNOWN)
  34.         return;
  35.     if (literal && ct != ELT) {    /* ignore while literal  */
  36.         put(buf);
  37.         return;
  38.     }
  39.  
  40. #ifdef DOUBLEWORD
  41.     if (flags == 2) {    /* check for 2-word command */
  42.         n = getwrd(buf, &i, xtoken);
  43.         if (n == 0) {
  44.             fprintf(stderr,"%c%s what ?\n", cchar, token);
  45.             return;
  46.         }
  47.         if ((at = comtype(xtoken, n, &defn, &flags)) == UNKNOWN) {
  48.             fprintf(stderr,"%c%s %s unknown.\n", cchar,
  49.             token,
  50.             xtoken);
  51.             return;
  52.         }
  53.         else
  54.             ct += at;
  55.     }
  56. #endif
  57.  
  58.     doesc(buf, variable, MAXLINE);    /* expand escapes */
  59.     n = getarg(buf, &i, xtoken);    /* first parameter*/
  60.     argtyp = '\n';    /* defaulted ** cludge ** */
  61.     val = 0;
  62.     if (n > 0) {
  63.         if (*xtoken == '+' || *xtoken == '-') {
  64.             argtyp = *xtoken;
  65.             val = atoi(xtoken+1);
  66.         }
  67.         else if (isdigit(*xtoken)) {
  68.             argtyp = 0;
  69.             val = atoi(xtoken);
  70.         }
  71.         else {
  72.             /* check some common flags */
  73.             if (strcmp("on",xtoken) == 0)
  74.                 onflag = TRUE;
  75.             else if (strcmp("off",xtoken) == 0)
  76.                 offlag = TRUE;
  77.         }
  78.     }
  79.  
  80.     switch(ct) {
  81.  
  82.     case MACRO:
  83.         eval(buf, defn);
  84.         break;
  85.     case FI:
  86.         brkeol();
  87.         fill = YES;
  88.         break;
  89.     case NF:
  90.         brkeol();
  91.         fill = NO;
  92.         break;
  93.     case BR:
  94.         brkeol();
  95.         break;
  96.     case LS:
  97.         set(&lsval, val, argtyp, 1, 1, HUGE);
  98.         break;
  99.     case CE:
  100.         brkeol();
  101.         if (onflag)
  102.             CEon = TRUE;
  103.         else if (offlag) {
  104.             CEon = FALSE;
  105.             ceval = 0;        /* reset */
  106.         }
  107.         else
  108.             set(&ceval, val, argtyp, 1, 0, HUGE);
  109.         break;
  110.     case UL:
  111.         if (onflag) {
  112.             ULon = TRUE;
  113.             break;
  114.         }
  115.         else if (offlag) {
  116.             ULon = FALSE;
  117.              ulval = 0;        /* reset */
  118.             break;
  119.         }
  120.         else 
  121.             set(&ulval, val, argtyp, 0, 1, HUGE);
  122.  
  123.         if (!isdigit(*xtoken)) {
  124.             if (strcmp("all",xtoken) == 0) {
  125.                     ulblnk = '_';
  126.                     ulval = 0;
  127.             }
  128.             else if (strcmp("words",xtoken) == 0) {
  129.                 ulblnk = ' ';
  130.                 ulval = 0;
  131.             }
  132.         }
  133.         break;
  134.     case BD:
  135.         if (bolding == YES) {
  136.             if (onflag)
  137.                 BDon = TRUE;
  138.             else if (offlag) {
  139.                 BDon = FALSE;
  140.                 boval = 0;    /* reset */
  141.             }
  142.             else
  143.                 set(&boval, val, argtyp, 0, 1, HUGE);
  144.         }
  145.         break;
  146.     case HE:
  147.         gettl(buf, ehead, ehlim);
  148.         gettl(buf, ohead, ohlim);
  149.         break;
  150.     case FO:
  151.         gettl(buf, efoot, eflim);
  152.         gettl(buf, ofoot, oflim);
  153.         break;
  154.     case BP:
  155.         if (paging == NO)
  156.             break;
  157.         brkeol();
  158.         if (lineno > 0)
  159.             space(HUGE);
  160.         set(&curpag, val, argtyp, curpag+1, -HUGE, HUGE);
  161.         newpag = curpag;
  162.         break;
  163.     case SP:
  164.         set(&spval, val, argtyp, 1, 0, HUGE);
  165.         space(spval);
  166.         break;
  167.     case IN:
  168.         brkeol();
  169.         set(&inval, val, argtyp, 0, 0, rmval-1);
  170.         tival = inval;
  171.         break;
  172.     case RM:
  173.         set(&rmval, val, argtyp, PAGEWIDTH, tival+1, HUGE);
  174.         break;
  175.     case TI:
  176.         brkeol();
  177.         set(&tival, val, argtyp, 0, 0, rmval);
  178.         break;
  179.     case LEX:    /****/
  180.         if ((xp = remove(xtoken,lextab)) != NULL) {
  181.             if (getwrd(buf, &i, variable) != 0)
  182.                 lexinstal(variable,xp->val,xp->flag,lextab);
  183.         }
  184.         else 
  185.             fprintf(stderr,"%s undefined.\n",xtoken);
  186.         break;
  187.     case PN:    /****/
  188.         if (strcmp(xtoken,"roman") == 0)
  189.             roman = TRUE;
  190.         else if (strcmp(xtoken,"arabic") == 0)
  191.             roman = FALSE;
  192.         else
  193.             fprintf(stderr,"%c%s does not have %s option.\n",
  194.             cchar,token,xtoken);
  195.         break;
  196.     case IG:    /****/
  197.         break;
  198.     case SET:    /****/
  199.         if (n > 0) {
  200.             if (isdigit(*xtoken)) {
  201.                 fprintf(stderr,"illegal variable name %s\n",
  202.                 xtoken);
  203.                 break;
  204.             }
  205.             *variable = '\0';
  206.             n = getarg(buf, &i, variable);
  207.             if (n <= 0) {
  208.                 fprintf(stderr,"%s: ", xtoken);
  209.                 gets(variable);
  210.  
  211.             }
  212.             if (*variable != '\0')
  213.                 install(xtoken, variable, gentab);
  214.         }
  215.         else
  216.             fprintf(stderr,"%c%s needs a variable name.\n",
  217.             cchar, token);
  218.         break;
  219.     case GET:    /****/
  220.         if (n > 0) {
  221.             if (isdigit(*xtoken)) {
  222.                 fprintf(stderr,"illegal variable name %s\n",
  223.                 xtoken);
  224.                 break;
  225.             }
  226.             *variable = '\0';
  227.             n = getarg(buf, &i, tbuf3); /* using temp buf3 */
  228.             if (n > 0) {
  229.                 fprintf(stderr,"%s", tbuf3);
  230.                 gets(variable);
  231.  
  232.             }
  233.             if (*variable != '\0')
  234.                 install(xtoken,variable, gentab);
  235.         }
  236.         else
  237.             fprintf(stderr,"%c%s needs a variable name.\n",
  238.             cchar, token);
  239.         break;
  240.     case CL:    /****/
  241.         if (argtyp == '\n') {
  242.             clast->level = 0;
  243.             clast->str = NULL;
  244.         }
  245.         else {
  246.             skipbl(buf,&i);
  247.             if (*(buf+i) == '\0')
  248.                 break;        /* no contents line here ! */
  249.             clast->level = val * 3; /* level * indent        */
  250.             n = i;
  251.             while(*(buf+n) != '\n')
  252.                 n++;
  253.             *(buf+n) = '\0';    /* destroy CR with a null  */
  254.             clast->str = strsave(buf+i);
  255.             clast->page = curpag;
  256.         }
  257.         clast->nextc = (struct clist *) malloc(sizeof(struct clist));
  258.         p_memoryus += sizeof(struct clist);
  259.         clast = clast->nextc;
  260.         clast->nextc = NULL;
  261.         break;
  262.     case PC:    /****/
  263.         brkeol();
  264.         clast = chead;
  265.         while(clast->nextc != NULL) {
  266.             if (clast->str == NULL)
  267.                 put("\n");
  268.             else {
  269.                 tival = (int) clast->level + inval;
  270.                 i = rmval - tival;
  271.                 docline(variable, i, clast->str, clast->page);
  272.                 put(variable);
  273.             }
  274.             clast = clast->nextc;
  275.         }
  276.         break;
  277.     case DBO:    /****/
  278.         bolding = NO;
  279.         break;
  280.     case EBO:    /****/
  281.         bolding = YES;
  282.         break;
  283.     case AP:    /****/
  284.         autopar = YES;
  285.         break;
  286.     case NAP:    /****/
  287.         autopar = NO;
  288.         break;
  289.     case SAV:    /****/
  290.         brkeol();
  291.         save();
  292.         break;
  293.     case RST:    /****/
  294.         brkeol();
  295.         restore();
  296.         break;
  297.     case NPA:    /****/
  298.         paging = NO;
  299.         savpl = plval;
  300.         plval = HUGE;
  301.         bottom = plval - m3val - m4val;
  302.         break;
  303.     case PGI:    /****/
  304.         bottom = lineno - 1;    /* force end-of-page */
  305.         brkeol();
  306.         plval = savpl;
  307.         break;
  308.     case LTR:    /****/
  309.         brkeol();
  310.         if (save()) {
  311.             inval = 0;
  312.             rmval = 132;
  313.             autopar = NO;
  314.             lsval = 0;
  315.             fill = NO;
  316.             literal = YES;
  317.         }
  318.         break;
  319.     case ELT:    /****/
  320.         restore();
  321.         literal = NO;
  322.         break;
  323.     case WR:    /****/
  324.         brkeol();
  325.         getpstr(buf+rest,special);
  326.         defn = special;
  327.         while(*defn)
  328.             putchar(*defn++);
  329.         break;
  330.     case PL:
  331.         if (paging == NO)
  332.             break;
  333.         set(&plval, val, argtyp, PAGELEN,
  334.         m1val + m2val + m3val + m4val + 1, HUGE);
  335.         bottom = plval - m3val - m4val;
  336.         break;
  337.     case PO:
  338.         set(&offset, val, argtyp, 0, 0, rmval - 1);
  339.         break;
  340.     case M1:
  341.         set(&m1val, val, argtyp, 3, 0,
  342.         plval - m2val - m3val - m4val - 1);
  343.         break;
  344.     case M2:
  345.         set(&m2val, val, argtyp, 2, 0,
  346.         plval - m1val - m3val - m4val - 1);
  347.         break;
  348.     case M3:
  349.         set(&m3val, val, argtyp, 2, 0,
  350.         plval - m1val - m2val - m4val - 1);
  351.         bottom = plval - m3val - m4val;
  352.         break;
  353.     case M4:
  354.         set(&m4val, val, argtyp, 3, 0,
  355.         plval - m1val - m2val - m3val - 1);
  356.         bottom = plval - m3val - m4val;
  357.         break;
  358.     case EH:
  359.         gettl(buf, ehead, ehlim);
  360.         break;
  361.     case OH:
  362.         gettl(buf, ohead, ohlim);
  363.         break;
  364.     case EF:
  365.         gettl(buf, efoot, eflim);
  366.         break;
  367.     case OF:
  368.         gettl(buf, ofoot, oflim);
  369.         break;
  370.     case CC:
  371.         cchar = *xtoken;
  372.         if (cchar == '\0' || cchar == '\n')
  373.             cchar = '.';
  374.         if ((lineno + val) > bottom && lineno <= bottom) {
  375.             space(val);
  376.             lineno = 0;
  377.         }
  378.         break;
  379.     case EC:
  380.         genesc = *xtoken;
  381.         if (genesc == '\0' || genesc == '\n')
  382.             genesc = '_';
  383.         break;
  384.     case NE:
  385.         if ((lineno + val) > bottom && lineno <= bottom) {
  386.             space(val);
  387.             lineno = 0;
  388.         }
  389.         break;
  390.     case BS:
  391.         set(&bsval, val, argtyp, 1, 0, HUGE);
  392.         break;
  393.     case JU:
  394.         rjust = YES;
  395.         break;
  396.     case NJ:
  397.         rjust = NO;
  398.         break;
  399.     case SO:
  400.         if (n <= 0)
  401.             return;
  402.         if (level + 1 == NFILES)
  403.             error("? SO commands nested too deeply.");
  404.         if ((infile[level + 1] = fopen(xtoken, "r")) != NULL) {
  405.             level++;
  406.             if (verbose == YES)
  407. #ifdef rainbow
  408.                 fprintf(stderr,"source \033[7m%s\033[0m\n",
  409.                     xtoken);
  410. #else
  411.                 fprintf(stderr,"source %s\n",xtoken);
  412. #endif
  413.         }
  414.         else
  415.             fprintf(stderr,"%s: cannot open.\n",xtoken);
  416.         break;
  417.     case OU:    /*****/
  418.         /* skip for now. */
  419.         break;
  420.  
  421.     case OE:    /*****/
  422.         /* skip for now. */
  423.         break;
  424.  
  425.     case CU:
  426.         ulblnk = '_';
  427.         set(&ulval, val, argtyp, 0, 1, HUGE);
  428.         break;
  429.     case DE:
  430.         dodef(buf, infile[level]);
  431.         break;
  432.     case NR:
  433.         if (n <= 0)
  434.             return;
  435.         if (*xtoken < 'a' || *xtoken > 'z')
  436.             error("invalid number register [%c].",*xtoken);
  437.  
  438.         val = getval(buf, &i, &argtyp);
  439.         set(&nr[xtoken[0] - 'a'], val, argtyp, 0, -HUGE, HUGE);
  440.         break;
  441.     case ST:
  442.         if (argtyp == '-')
  443.             spval = plval;
  444.         else
  445.             spval = 0;
  446.         set(&spval, val, argtyp, 0, 1, bottom);
  447.         if (spval > lineno && lineno == 0)
  448.             phead();
  449.         if (spval > lineno)
  450.             space(spval - lineno);
  451.         break;
  452.     case RESET:    /****/
  453.         finit();
  454.         break;
  455.     default:
  456.         error("? Botch in command.");
  457.         break;
  458.     }
  459. }
  460.  
  461. /*
  462.  * comtype - decode the command type
  463.  *
  464.  */
  465. int
  466. comtype(buf, siz, defn, flags)
  467. char buf[];
  468. int siz;
  469. char **defn;
  470. int *flags;
  471. {
  472.  
  473.     struct hashlist *np;
  474.     struct lexlist *xp;
  475.     extern    struct lexlist *lexlook();
  476.     int i,comtyp;
  477.     char c1,c2;
  478.  
  479.  
  480. #ifdef DEBUG
  481.     printf("comtype: %s (token)\n",token1);
  482. #endif
  483.  
  484.     if ((np = lookup(buf, macrotab)) != NULL) {
  485.         *defn=np->def;
  486.         return(MACRO);
  487.     }
  488.     comtyp = UNKNOWN;
  489.  
  490.     if (*buf == '#' || *buf == '!')
  491.         return(comtyp);
  492.  
  493.     if ((xp = lexlook(buf,lextab)) != NULL)
  494.         if (onlyrunoff && (xp->flag != RUNOFF)) {
  495.             fprintf(stderr,"%c%s is not a runoff command.\n",
  496.             cchar,buf);
  497.             return(UNKNOWN);
  498.         }
  499.         else {    
  500.             comtyp = xp->val;
  501.             *flags = xp->flag;
  502.         }
  503.  
  504.     if (comtyp == UNKNOWN)
  505.         fprintf(stderr,"unknown command %c%s\n",cchar,buf);
  506.     return(comtyp);
  507. }
  508.